package it.unica.informatica.enotes.manager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

import it.unica.informatica.enotes.NotesActivity;
import it.unica.informatica.enotes.R;
import it.unica.informatica.enotes.notes.AttachmentItem;

/**
 * This class perform all the operation related to the storing of multimedia contents
 *
 * @author Mirko Marras
 * @version 1.0
 */
public class AttachmentsStoringManager {

   /**
    * The prefix used for the folder associated to the attachments of a note
    */
   public static final String FOLDER_PREFIX = "ID";

   /**
    * The base directory used to save the directories associated to the attachments of the notes
    */
   public static File baseExternalDir = null;

   /**
    * The base cache directory used to save temporary files
    */
   public static String baseCacheDir = "";

   /**
    * The ID value associated to a folder that contains the attachments of an import note during its import
    */
   public static final Long IMPORT_PREFIX = Long.valueOf(-1);

   /**
    * The ID value associated to a folder that contains the attachments of a note to being created
    */
   public static final Long CREATE_PREFIX = Long.valueOf(0);


   /**
    * Set base directories managed by the AttachmentsAcquisitionManager
    *
    * @param activity
    */
   public static void setBaseDirectories(NotesActivity activity) {
      baseCacheDir = activity.getExternalCacheDir() + File.separator;
      baseExternalDir = activity.getExternalFilesDir(activity.getString(R.string.app_name));
   }

   /**
    * Copy a file picked or create at the moment by the user to the external storage of the application
    *
    * @param src    The file to copy
    * @param noteId The id of the note to which the attachment belongs
    */
   public static String copyToAppMemory(File src, Long noteId) {
      /* The standard name of the directory for the attachments of a note is ID<id> es. ID8 */
      final String dirName = FOLDER_PREFIX + noteId;
      String finalName;
      String extension;

      /* If not exists, create the directory for the note */
      File noteDirectory = new File(baseExternalDir, dirName);
      noteDirectory.mkdirs();

      /* Create the destination file */
      finalName = src.getName();
      extension = src.getName().substring(src.getName().lastIndexOf("."));
      File dst = new File(noteDirectory, src.getName());
      if (dst.exists()) {
         int counter = 0;
            /* Append a number to the name of the file */
         while (dst.exists()) {
            finalName = src.getName().substring(0, src.getName().lastIndexOf("."))
                    + "-"
                    + counter
                    + extension;
            counter++;
            dst = new File(noteDirectory, finalName);
         }
      }

      /* Copy the content of the source file in the destination file */
      FileChannel inChannel = null;
      FileChannel outChannel = null;
      try {
         inChannel = new FileInputStream(src).getChannel();
         outChannel = new FileOutputStream(dst).getChannel();
         inChannel.transferTo(0, inChannel.size(), outChannel);
      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         try {
            if (inChannel != null)
               inChannel.close();
            if (outChannel != null)
               outChannel.close();
         } catch (IOException e) {
            e.printStackTrace();
         }
      }

      return finalName;
   }

   /**
    * Delete a file associated to an attachment for a particular note
    *
    * @param name   The name of the attachment to delete
    * @param noteId The id of the note to which the attachment belongs
    */
   public static void deleteFromAppMemory(String name, Long noteId) {
      final String dirName = FOLDER_PREFIX + noteId;
      File noteDirectory = new File(baseExternalDir, dirName);
      File dst = new File(noteDirectory, name);
      if (dst.exists()) dst.delete();
   }

   /**
    * Rename a file associated to an attachment for a particular note
    *
    * @param oldName The old name of the attachment
    * @param newName The new name of the attachment
    * @param noteId  The id of the note to which the attachment belongs
    */
   public static void renameFileAppMemory(String oldName, String newName, Long noteId) {
      final String dirName = FOLDER_PREFIX + noteId;
      File noteDirectory = new File(baseExternalDir, dirName);
      File from = new File(noteDirectory, oldName);
      File to = new File(noteDirectory, newName);
      from.renameTo(to);
   }

   /**
    * Rename the directory associated to a note with a different note ID
    *
    * @param oldId The id of the directory to rename
    * @param newId The new id for the directory
    */
   public static void renameDirAppMemory(Long oldId, Long newId) {
      final String oldDirName = FOLDER_PREFIX + oldId;
      final String newDirName = FOLDER_PREFIX + newId;
      File from = new File(baseExternalDir, oldDirName);
      File to = new File(baseExternalDir, newDirName);
      from.renameTo(to);
   }

   /**
    * Get a file associated to the attachment that belongs to a certain note
    *
    * @param noteId     The id of the note to which the attachment belongs
    * @param attachment The attachment to associate to the file
    * @return The file associated to the attachment that belongs to a certain note
    */
   public static File getAttachmentFile(Long noteId, AttachmentItem attachment) {
      final String dirName = FOLDER_PREFIX + noteId;
      File noteDirectory = new File(baseExternalDir, dirName);
      return new File(noteDirectory, attachment.getName());
   }

   /**
    * Delete the directory associated to a note with its content
    *
    * @param noteId The id of the note to which the directory is associated
    */
   public static void deleteDirAppMemory(Long noteId) {
      final String dirName = FOLDER_PREFIX + noteId;
      File dir = new File(baseExternalDir, dirName);
      if (dir.isDirectory()) {
         String[] children = dir.list();
         for (int i = 0; i < children.length; i++) {
            new File(dir, children[i]).delete();
         }
      }
      if (dir.exists()) dir.delete();
   }

   /**
    * Delete the content of the cache file of the application
    */
   public static void deleteCache() {
      try {
         File dir = new File(baseCacheDir);
         if (dir != null && dir.isDirectory()) {
            String[] children = dir.list();
            for (int i = 0; i < children.length; i++) {
               File cacheFile = new File(dir, children[i]);
               cacheFile.delete();
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

}
